<template>
  <div class="el-tree-select">
    <el-select v-if="type == 'tree'" style="width: 100%" v-model="valueId" ref="treeSelect" :filterable="true"
      :clearable="true" @clear="clearHandle" :filter-method="selectFilterData" :placeholder="placeholder">
      <el-option :value="valueId" :label="valueTitle" v-loading="loading">
        <el-tree id="tree-option" ref="selectTree" :load="loadNode" lazy :data="options" :props="objMap"
          :node-key="objMap.value" :expand-on-click-node="false" :default-expanded-keys="defaultExpandedKey"
          :filter-node-method="filterNode" @node-click="handleNodeClick"></el-tree>
      </el-option>
    </el-select>
    <el-row v-else :gutter="20">
      <el-col :span="8">
        <matic-select v-model:value="province" :objMap="{ value: 'id', label: 'name' }"
          :url="`area/getSonArea/forManager?parentId=${1}`" @change="changeProvince"></matic-select>
      </el-col>
      <el-col :span="8">
        <matic-select v-model:value="city" :objMap="{ value: 'id', label: 'name' }"
          :url="province ? `area/getSonArea/forManager?parentId=${province}` : ''" @change="changeCity"></matic-select>
      </el-col>
      <el-col :span="8">
        <matic-select v-model:value="district" :objMap="{ value: 'id', label: 'name' }"
          :url="city ? `area/getSonArea/forManager?parentId=${city}` : ''" @change="changeDistrict"></matic-select>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import request from '@/utils/request'
const { proxy } = getCurrentInstance();

const loading = ref(false);
const options = ref([]);

const props = defineProps({
  /* 配置项 */
  objMap: {
    type: Object,
    default: () => {
      return {
        value: 'id', // ID字段名
        label: 'name', // 显示名称
        children: 'cityList', // 子级字段名
        isLeaf: 'leaf',
      }
    }
  },
  /**当前双向数据绑定的值 */
  value: {
    type: [String, Number],
    default: ''
  },
  /**当前双向数据绑定的值 */
  provinceId: {
    type: [String, Number],
    default: ''
  },
  /**当前双向数据绑定的值 */
  cityId: {
    type: [String, Number],
    default: ''
  },
  /**当前双向数据绑定的值 */
  districtId: {
    type: [String, Number],
    default: ''
  },



  /**输入框内部的文字 */
  placeholder: {
    type: String,
    default: ''
  },
  /**输入框内部的文字 */
  type: {
    type: String,
    default: 'select'
  },
  url: {
    type: String,
    default: 'area/getSonArea/forManager?parentId=1'
  }
})

const emit = defineEmits();
const province = computed({
  get() {
    return props.provinceId
  },
  set(val) {
    emit('update:provinceId', val)
  }
})
const city = computed({
  get() {
    return props.cityId
  },
  set(val) {
    emit('update:cityId', val)
  }
})
const district = computed({
  get() {
    return props.districtId
  },
  set(val) {
    emit('update:districtId', val)
  }
})

const valueId = computed({
  get: () => props.value,
  set: (val) => {
    emit('update:value', val)
  }
});
const valueTitle = ref('');
const defaultExpandedKey = ref([]);

const obj = ref({ province: {}, city: {}, district: {} })

const changeProvince = (data) => {
  nextTick(() => {
    obj.value.province = data
    city.value = ''
    obj.value.city = {}
    district.value = ''
    obj.value.district = {}
    change()
  })
}
const changeCity = (data) => {
  nextTick(() => {
    obj.value.city = data
    district.value = ''
    obj.value.district = {}
    change()
  })
}
const changeDistrict = (data) => {
  nextTick(() => {
    obj.value.district = data
    change()
  })
}

const change = () => {
  nextTick(() => {
    emit('change', obj.value)
  })
}

function initHandle() {
  nextTick(() => {
    const selectedValue = valueId.value;
    if (selectedValue !== null && typeof (selectedValue) !== 'undefined') {
      const node = proxy.$refs.selectTree.getNode(selectedValue)
      if (node) {
        valueTitle.value = node.data[props.objMap.label]
        proxy.$refs.selectTree.setCurrentKey(selectedValue) // 设置默认选中
        defaultExpandedKey.value = [selectedValue] // 设置默认展开
      }
    } else {
      clearHandle()
    }
  })
}
function handleNodeClick(node) {
  valueTitle.value = node[props.objMap.label]
  valueId.value = node[props.objMap.value];
  defaultExpandedKey.value = [];
  proxy.$refs.treeSelect.blur()
  selectFilterData('')
}
function selectFilterData(val) {
  proxy.$refs.selectTree.filter(val)
}
function filterNode(value, data) {
  if (!value) return true
  return data[props.objMap['label']].indexOf(value) !== -1
}
function clearHandle() {
  valueTitle.value = ''
  valueId.value = ''
  defaultExpandedKey.value = [];
  clearSelected()
}
function clearSelected() {
  const allNode = document.querySelectorAll('#tree-option .el-tree-node')
  allNode.forEach((element) => element.classList.remove('is-current'))
}

onMounted(() => {
  if (props.type == 'tree') {
    onload()
    initHandle()
  }
})

watch(valueId, () => {
  initHandle();
})

const onload = () => {
  nextTick(() => {
    request.get(props.url).then((res) => {
      if (res.code == 200) {
        // res.result.map(e => e.cityList.map(i => i.cityList = []))
        options.value = res.result;
      }
    });
  });
}

const loadNode = (node, resolve) => {
  if (node.data.cityList) {
    return resolve(node.data.cityList)
  } else if (node.data.id) {
    request.get(`area/getSonArea/forManager?parentId=${node.data.id}`).then((res) => {
      if (res.code == 200) {
        res.result = res.result || []
        // res.result = res.result.map(e => ({ ...e, leaf: true }))
        resolve(res.result)
      }
    });
  } else {
    resolve([])
  }
}




</script>

<style lang='scss' scoped>
@import "@/assets/styles/variables.module.scss";

.el-tree-select {
  width: 100%;
}

.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
  padding: 0;
  background-color: #fff;
  height: auto;
}

.el-select-dropdown__item.selected {
  font-weight: normal;
}

:deep(.el-tree-node__content) {
  height: auto;
  padding: 0 20px;
  box-sizing: border-box;
}

:deep(.el-tree-node__content:hover),
:deep(.el-tree-node__content:active),
:deep(.is-current > div:first-child),
:deep(.el-tree-node__content:focus) {
  background-color: mix(#fff, $--color-primary, 90%);
  color: $--color-primary;
}
</style>